package fr.pud.client.view;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import fr.pud.client.controller.InputCheck;
import fr.pud.client.controller.fleet.ApplyModificationFleet;
import fr.pud.client.controller.fleet.CheckAndAddVehicleToFleet;
import fr.pud.client.controller.fleet.CloseVehicleFrame;
import fr.pud.client.controller.fleet.DeleteVehicleFromFleet;
import fr.pud.client.controller.fleet.ModifyVehicleFromFleet;
import fr.pud.client.i18n.LanguagesConstants;
import fr.pud.client.model.Fleet;
import fr.pud.client.model.PUDStationDatabase;
import fr.pud.client.model.Vehicle;

/**
 * 3 avr. 2012 - Projet_Ose
 * @author Simon Devineau, Adrien Hierry, Leopold Houdin, Pierre Reliquet
 *         Ecole des Mines de Nantes
 *         AddVehicleFrame.java
 */
public class AddVehicleFrame extends JFrame {
    /**
     * The serial UID
     */
    private static final long      serialVersionUID = 45672619750577647L;
    /**
     * The single instance of the AddVehicleFrame.
     */
    private static AddVehicleFrame instance         = null;

    /**
     * @return the instance
     */
    public static AddVehicleFrame getInstance() {
        initialization();
        return instance;
    }

    /**
     * This method initializes the JFrame.
     */
    private static void initialization() {
        if (instance == null) {
            instance = new AddVehicleFrame();
        }
    }

    /**
     * The JTextField where the capacity will be typed.
     */
    private JTextField             capacity          = new JTextField(2);
    /**
     * The JTextField where the max drive duration will be typed by the user.
     */
    private JTextField             maxDriveDuration  = new JTextField(2);
    /**
     * The JCombobox where the address of the starting point will be chosen.
     */
    private JComboBox              startingPoint;
    /**
     * The JCombobox where the address of the ending point will be chosen.
     */
    private JComboBox              endingPoint;
    /**
     * The JButton to add a vehicle to the fleet.
     */
    private JButton                add               = new JButton(
                                                             new CheckAndAddVehicleToFleet());
    /**
     * The JButton to delete a vehicle from the fleet.
     */
    private JButton                delete            = new JButton(
                                                             new DeleteVehicleFromFleet());
    /**
     * The JButton to modify a vehicle from the fleet.
     */
    private JButton                modify            = new JButton(
                                                             new ModifyVehicleFromFleet());
    /**
     * The JButton to apply the modification.
     */
    private JButton                applyModification = new JButton(
                                                             new ApplyModificationFleet());
    /**
     * The JButton to close the frame..
     */
    private JButton                close             = new JButton(
                                                             new CloseVehicleFrame());
    /**
     * A JList where the fleet will be summarize.
     */
    private SummarizeInfo<Vehicle> fleetInformation;

    /**
     * A frame which allows to the user to add,modify, delete a vehicle to the
     * fleet.
     */
    public AddVehicleFrame() {
        this.prepareFrame();
        this.putTogetherPanel();
        this.pack();
        this.placeFrame();
    }

    @Override
    public void dispose() {
        super.dispose();
        MainFrame.getSingleton().setEnabled(true);
    }

    /**
     * @return the JButton add
     */
    public JButton getAdd() {
        return this.add;
    }

    /**
     * @return the applyModification
     */
    public JButton getApplyModification() {
        return this.applyModification;
    }

    /**
     * @return the capacity
     */
    public JTextField getCapacity() {
        initialization();
        return this.capacity;
    }

    /**
     * @return the close
     */
    public JButton getClose() {
        return this.close;
    }

    /**
     * @return the delete
     */
    public JButton getDelete() {
        return this.delete;
    }

    /**
     * @return the endingPoint
     */
    public JComboBox getEndingPoint() {
        initialization();
        return this.endingPoint;
    }

    /**
     * @return the fleetInformation
     */
    public SummarizeInfo<Vehicle> getFleetInformation() {
        return this.fleetInformation;
    }

    /**
     * @return the maxDriveDuration
     */
    public JTextField getMaxDriveDuration() {
        initialization();
        return this.maxDriveDuration;
    }

    /**
     * @return the modify
     */
    public JButton getModify() {
        return this.modify;
    }

    /**
     * @return the startingPoint
     */
    public JComboBox getStartingPoint() {
        initialization();
        return this.startingPoint;
    }

    /**
     * Place the frame
     */
    private void placeFrame() {
        this.setLocation((int) Toolkit.getDefaultToolkit().getScreenSize()
                .getWidth()
                / 2 - this.getWidth() / 2, (int) Toolkit.getDefaultToolkit()
                .getScreenSize().getHeight()
                / 2 - this.getHeight());
    }

    /**
     * Prepare the section concerning the capacity of the vehicle.
     * @return
     */
    private JPanel prepareCapacity() {
        JPanel capacityPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel capacityLabel = new JLabel(
                LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.VEHICLE_CAPACITY) + " : ");
        capacityPanel.add(capacityLabel);
        capacityPanel.add(this.capacity);
        return capacityPanel;
    }

    /**
     * Prepare the east panel where all the information needed to create a
     * vehicle are placed.
     */
    private JPanel prepareEasthPanel() {
        this.prepareKeyListener();
        JPanel pan = new JPanel();
        pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
        pan.add(this.prepareCapacity());
        pan.add(this.prepareMaxDrive());
        pan.add(this.prepareStartingPoint());
        pan.add(this.prepareEndingPoint());
        return pan;
    }

    /**
     * Prepare the JCombobox used to choose the ending point of the vehicle.
     * @return
     */
    private JPanel prepareEndingPoint() {
        JPanel endingPointPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        this.endingPoint = new JComboBox(PUDStationDatabase.getInstance()
                .toArray());
        JLabel endingPoint = new JLabel(
                LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.VEHICLE_ENDING_POINT_ADDRESS)
                        + " : ");
        endingPointPanel.add(endingPoint);
        endingPointPanel.add(this.endingPoint);
        return endingPointPanel;
    }

    /**
     * Prepare the frame.
     */
    private void prepareFrame() {
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        this.setTitle(LanguagesConstants.LANGUAGE
                .getString(LanguagesConstants.ADD_VEHICLE));
        this.setAlwaysOnTop(true);
        this.setVisible(true);
        this.getContentPane().setLayout(
                new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
    }

    /**
     * Add KeyListener to the JtextField to check the data input by the user.
     */
    private void prepareKeyListener() {
        this.capacity.addKeyListener(new InputCheck(this.capacity,
                InputCheck.INTEGER_ONLY));
        this.maxDriveDuration.addKeyListener(new InputCheck(
                this.maxDriveDuration, InputCheck.INTEGER_ONLY));
    }

    /**
     * Prepare the section concerning the max drive duration of the vehicle.
     * @return
     */
    private JPanel prepareMaxDrive() {
        JPanel maxDrivePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel maxDriveDuration = new JLabel(
                LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.VEHICLE_AUTONOMY) + " : ");
        maxDrivePanel.add(maxDriveDuration);
        maxDrivePanel.add(this.maxDriveDuration);
        return maxDrivePanel;
    }

    /**
     * Prepare the south panel where the button modify, delete add close and
     * apply modification are placed.
     */
    private JPanel prepareSouthPanel() {
        JPanel southPan = new JPanel(new FlowLayout());
        southPan.add(this.modify);
        southPan.add(this.delete);
        southPan.add(this.add);
        southPan.add(this.close);
        this.applyModification.setVisible(false);
        southPan.add(this.applyModification);
        return southPan;
    }

    /**
     * Prepare the JCombobox where the user will choose the address of the
     * starting point of the vehicle.
     * @return
     */
    private JPanel prepareStartingPoint() {
        JPanel startingPointPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        this.startingPoint = new JComboBox(PUDStationDatabase.getInstance()
                .toArray());
        JLabel startingPoint = new JLabel(
                LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.VEHICLE_STARTING_POINT_ADDRESS)
                        + " : ");
        startingPointPanel.add(startingPoint);
        startingPointPanel.add(this.startingPoint);
        return startingPointPanel;
    }

    /**
     * Put together the Jlist, the panel for input data and the panel with all
     * the buttons.
     */
    private void putTogetherPanel() {
        this.fleetInformation = new SummarizeInfo<Vehicle>(Fleet.getInstance()
                .getVehicles(), Fleet.getInstance());
        JScrollPane scroll = new JScrollPane(this.fleetInformation);
        this.getContentPane().add(scroll);
        this.getContentPane().add(this.prepareEasthPanel());
        this.getContentPane().add(this.prepareSouthPanel());
    }

    /**
     * @param aValidate
     *            the validate to set
     */
    public void setAdd(JButton aValidate) {
        this.add = aValidate;
    }

    /**
     * @param aApplyModification
     *            the applyModification to set
     */
    public void setApplyModification(JButton aApplyModification) {
        this.applyModification = aApplyModification;
    }

    /**
     * @param aCapacity
     *            the capacity to set
     */
    public void setCapacity(JTextField aCapacity) {
        initialization();
        this.capacity = aCapacity;
    }

    /**
     * @param close
     *            the close to set
     */
    public void setClose(JButton close) {
        this.close = close;
    }

    /**
     * @param aDelete
     *            the delete to set
     */
    public void setDelete(JButton aDelete) {
        this.delete = aDelete;
    }

    /**
     * @param aEndingPoint
     *            the endingPoint to set
     */
    public void setEndingPoint(JComboBox aEndingPoint) {
        initialization();
        this.endingPoint = aEndingPoint;
    }

    /**
     * @param aFleetInformation
     *            the fleetInformation to set
     */
    public void setFleetInformation(SummarizeInfo<Vehicle> aFleetInformation) {
        this.fleetInformation = aFleetInformation;
    }

    /**
     * @param aInstance
     *            the instance to set
     */
    public void setInstance(AddVehicleFrame aInstance) {
        initialization();
        instance = aInstance;
    }

    /**
     * @param aMaxDriveDuration
     *            the maxDriveDuration to set
     */
    public void setMaxDriveDuration(JTextField aMaxDriveDuration) {
        initialization();
        this.maxDriveDuration = aMaxDriveDuration;
    }

    /**
     * @param aModify
     *            the modify to set
     */
    public void setModify(JButton aModify) {
        this.modify = aModify;
    }

    /**
     * @param aStartingPoint
     *            the startingPoint to set
     */
    public void setStartingPoint(JComboBox aStartingPoint) {
        initialization();
        this.startingPoint = aStartingPoint;
    }
}
